package com.wootion.cims.module.systemsetting.role.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wootion.cims.dao.*;
import com.wootion.cims.general.utils.GetIp;
import com.wootion.cims.module.systemsetting.log.model.SysLog;
import com.wootion.cims.module.systemsetting.role.model.SysMenu;
import com.wootion.cims.module.systemsetting.role.model.SysRole;
import com.wootion.cims.module.systemsetting.user.model.SysUserRole;
import com.wootion.cims.module.systemsetting.role.service.SysRoleService;
import com.wootion.cims.module.systemsetting.role.model.SysRoleMenu;
import com.wootion.cims.module.systemsetting.user.model.User;
import com.wootion.cims.response.ResponseResult;
import com.wootion.cims.response.ResultCode;
import com.wootion.cims.shiro.utils.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRole> implements SysRoleService {

    @Autowired(required = false)
    SysRoleDao sysRoleDao;

    @Autowired(required = false)
    SysRoleMenuDao sysRoleMenuDao;

    @Autowired(required = false)
    SysMenuDao sysMenuDao;

    @Autowired(required = false)
    SysUserRoleDao sysUserRoleDao;

    @Autowired(required = false)
    SysLogDao sysLogDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult insert(JSONObject jsonObject) {
        SysRole sysRole = JSONObject.parseObject(jsonObject.toJSONString(), SysRole.class);
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name",sysRole.getName());
        queryWrapper.eq("enabled",true);
        SysRole sysRole1 = sysRoleDao.selectOne(queryWrapper);
        if (Optional.ofNullable(sysRole1).isPresent()){
            return ResponseResult.builder().code(ResultCode.WRONG_REQUEST_PARAMETER.getCode()).message("角色名称已存在").build();
        }

        UUID uuid= UUID.randomUUID();
        sysRole.setId(uuid.toString()).setEnabled(true).setRoleKey("community:admin").setCreateTime(new Date());

        int insert = sysRoleDao.insert(sysRole);

        if (insert>0){
            JSONArray menus = jsonObject.getJSONArray("menus");
            if (Optional.ofNullable(menus).isPresent()) {
                List<String> list1 = menus.toJavaList(String.class);
                for (String s : list1) {
                    QueryWrapper<SysMenu> queryWrapper1 = new QueryWrapper<>();
                    queryWrapper1.eq("value", s);
                    SysMenu sysMenu = sysMenuDao.selectOne(queryWrapper1);
                    if (Optional.ofNullable(sysMenu).isPresent()) {
                        sysRoleMenuDao.insert(new SysRoleMenu().setId(UUID.randomUUID().toString()).setMenuId(sysMenu.getId()).setRoleId(uuid.toString()));
                    }
                }
            }
            return ResponseResult.builder().code(ResultCode.NORMAL.getCode()).message(ResultCode.NORMAL.getMessage()).build();
        }else {
            return ResponseResult.builder().code(ResultCode.SYSTEM_ERROR.getCode()).message(ResultCode.SYSTEM_ERROR.getMessage()).build();
        }
    }

    @Override
    public ResponseResult update(HttpServletRequest request,JSONObject jsonObject) {
        SysRole sysRole = JSONObject.parseObject(jsonObject.toJSONString(), SysRole.class);
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name",sysRole.getName());
        queryWrapper.eq("enabled",true);
        SysRole sysRole1 = sysRoleDao.selectOne(queryWrapper);
        if (Optional.ofNullable(sysRole1).isPresent() && !sysRole1.getId().equals(sysRole.getId())){
            return ResponseResult.builder().code(ResultCode.WRONG_REQUEST_PARAMETER.getCode()).message("角色名称已存在").build();
        }
        SysRole sysRole2 = sysRoleDao.selectById(sysRole.getId());
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId,sysRole.getId());
        List<SysRoleMenu> sysRoleMenus1 = sysRoleMenuDao.selectList(wrapper);
        List<String> collect = sysRoleMenus1.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        List<SysMenu> sysMenus = sysMenuDao.findByIds(collect);
        List<String> menusName = sysMenus.stream().map(SysMenu::getName).filter(name ->!(name.equals("登录验证"))).collect(Collectors.toList());

        int insert = sysRoleDao.updateById(sysRole);


        SysLog sysLog = new SysLog();
        sysLog.setIncident("角色信息");
        sysLog.setType("修改");
        sysLog.setValue("系统日志");
        sysLog.setCreateTime(new Date());
        sysLog.setIp(GetIp.getIpAddr(request));
        User user2 = (User) ShiroUtils.getSubject().getPrincipal();
        sysLog.setOperator(user2.getUsername());
        sysLog.setContent("角色名称:"+sysRole.getName());
        StringBuilder builder = new StringBuilder();
        if(!sysRole.getName().equals(sysRole2.getName())){
            builder.append("角色名称,修改前:").append(sysRole2.getName()).append(",修改后:").append(sysRole.getName()).append("。");
        }
        if (insert>0){
            sysLog.setResult("成功");
            QueryWrapper<SysRoleMenu> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("role_id",sysRole.getId());
            List<SysRoleMenu> sysRoleMenus = sysRoleMenuDao.selectList(queryWrapper2);
            for (SysRoleMenu s : sysRoleMenus){
                sysRoleMenuDao.deleteById(s.getId());
            }

            JSONArray menus = jsonObject.getJSONArray("menus");
            if (Optional.ofNullable(menus).isPresent()) {
                List<String> list1 = menus.toJavaList(String.class);
                for (String s : list1) {
                    QueryWrapper<SysMenu> queryWrapper1 = new QueryWrapper<>();
                    queryWrapper1.eq("value", s);
                    SysMenu sysMenu = sysMenuDao.selectOne(queryWrapper1);
                    if (Optional.ofNullable(sysMenu).isPresent()) {
                        sysRoleMenuDao.insert(new SysRoleMenu().setId(UUID.randomUUID().toString()).setMenuId(sysMenu.getId()).setRoleId(sysRole.getId()));
                    }
                }
            }

            SysRole sysRole3 = sysRoleDao.selectById(sysRole.getId());
            LambdaQueryWrapper<SysRoleMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(SysRoleMenu::getRoleId,sysRole3.getId());
            List<SysRoleMenu> sysRoleMenus2 = sysRoleMenuDao.selectList(wrapper);
            List<String> collect1 = sysRoleMenus2.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
            List<SysMenu> sysMenus2 = sysMenuDao.findByIds(collect1);
            List<String> menusName2 = sysMenus2.stream().map(SysMenu::getName).filter(name->!(name.equals("登录验证"))).collect(Collectors.toList());
            builder.append("菜单权限,修改前:").append(menusName).append(",修改后:").append(menusName2).append("。");
            sysLog.setDetails(builder.toString());
            sysLogDao.insert(sysLog);
            return ResponseResult.builder().code(ResultCode.NORMAL.getCode()).message(ResultCode.NORMAL.getMessage()).build();
        }else {
            sysLog.setResult("失败");
            sysLogDao.insert(sysLog);
            return ResponseResult.builder().code(ResultCode.SYSTEM_ERROR.getCode()).message(ResultCode.SYSTEM_ERROR.getMessage()).build();
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteById(String parseObject) {

        QueryWrapper<SysUserRole> queryWrapper4 = new QueryWrapper<>();
        queryWrapper4.eq("role_id",parseObject);
        List<SysUserRole> sysUserRoles = sysUserRoleDao.selectList(queryWrapper4);
        if (!sysUserRoles.isEmpty()){
            return ResponseResult.builder().code(ResultCode.SYSTEM_ERROR.getCode()).message("此角色已被使用,请清除后再尝试删除").build();
        }

        SysRole sysRole = sysRoleDao.selectById(parseObject);
        int i = sysRoleDao.updateById(sysRole.setEnabled(false));

        if (i>0){
            QueryWrapper<SysRoleMenu> queryWrapper3 = new QueryWrapper<>();
            queryWrapper3.eq("role_id",parseObject);
            List<SysRoleMenu> selectList = sysRoleMenuDao.selectList(queryWrapper3);
            for (SysRoleMenu sysRoleMenu : selectList){
                sysRoleMenuDao.deleteById(sysRoleMenu.getId());
            }

//            QueryWrapper<SysUserRole> queryWrapper4 = new QueryWrapper<>();
//            queryWrapper4.eq("role_id",parseObject);
//            List<SysUserRole> sysUserRoles = sysUserRoleDao.selectList(queryWrapper4);
//            for (SysUserRole sysUserRole : sysUserRoles){
//                sysUserRoleDao.deleteById(sysUserRole.getId());
//            }
            return ResponseResult.builder().code(ResultCode.NORMAL.getCode()).message(ResultCode.NORMAL.getMessage()).build();
        }else {
            return ResponseResult.builder().code(ResultCode.SYSTEM_ERROR.getCode()).message(ResultCode.SYSTEM_ERROR.getMessage()).build();
        }
    }

    @Override
    public ResponseResult selectPage(Integer limit, Integer page) {
        Page<SysRole> page1 = new Page<>(page,limit);

        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("enabled",true);
//        queryWrapper.like("name",condition);

        List<JSONObject> list = new ArrayList<>();

        Page<SysRole> userPage = sysRoleDao.selectPage(page1, queryWrapper);
        for (SysRole sysRole : userPage.getRecords()){
            QueryWrapper<SysRoleMenu> queryWrapper1 = new QueryWrapper();
            queryWrapper1.eq("role_id",sysRole.getId());
            List<SysRoleMenu> sysRoleMenus = sysRoleMenuDao.selectList(queryWrapper1);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id",sysRole.getId());
            jsonObject.put("name",sysRole.getName());
            jsonObject.put("number",sysRoleMenus.size());
            list.add(jsonObject);
        }

        Page<JSONObject> page2 = new Page<>();
//        page2.setPages(userPage.getPages());
        page2.setMaxLimit(userPage.getMaxLimit());
        page2.setRecords(list);
        page2.setSize(userPage.getSize());
        page2.setCurrent(userPage.getCurrent());
        page2.setTotal(userPage.getTotal());
        return ResponseResult.builder().code(ResultCode.NORMAL.getCode()).message(ResultCode.NORMAL.getMessage()).data(page2).build();
    }

    @Override
    public ResponseResult findById(String s) {
        SysRole sysRole = sysRoleDao.selectById(s);
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(sysRole));
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id",s);
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuDao.selectList(queryWrapper);
        List<SysMenu> list = new ArrayList<>();
        for (SysRoleMenu sysRoleMenu : sysRoleMenus){
            SysMenu byId = sysMenuDao.selectById(sysRoleMenu.getMenuId());
            list.add(byId);
        }
        jsonObject.put("menus",list);
        return ResponseResult.builder().code(ResultCode.NORMAL.getCode()).message(ResultCode.NORMAL.getMessage()).data(jsonObject).build();
    }

    @Override
    public ResponseResult selectAll() {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("enabled",true);
        queryWrapper.ne("role_key","street:admin");
        List<SysRole> sysRoles = sysRoleDao.selectList(queryWrapper);
        return ResponseResult.builder().code(ResultCode.NORMAL.getCode()).message(ResultCode.NORMAL.getMessage()).data(sysRoles).build();
    }
}
